package com.lzx.hbh_system.error;

import com.lzx.hbh_system.util.responseEntity.RespOutMsgHeader;
import com.lzx.hbh_system.util.responseEntity.ResponseView;
import com.lzx.hbh_system.util.staitcParma.ResultEnum;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authz.AuthorizationException;
import org.apache.shiro.authz.UnauthorizedException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;

/**
 * 最终继承到了 servlet 的 Filter 类， Filter 处理是在控制器之前的， 所以由 @ControllerAdvice注解的全局异常处理器无法处理这里的异常(@ControllerAdvice是由spring 提供的增强控制器) 。
 * 由于Shiro的过滤器的继承链路导致我们使用的全局异常捕捉注解的异常无法处理
 * 解决方案 ： 使用JWTFilter中getSubject.login时，捕捉JWTRealm抛出的AuthenticationException的父异常，
 * 判断异常字符串选择以统一的响应结果重定向到特定的Controller中处理并响应JSON给前端。
 *
 * @RestControllerAdvice 注释为 全局异常捕捉类 并且返回参数以JSON格式返回
 * 增强的 Controller。使用这个 Controller ，可以实现三个方面的功能：
 *
 * 1全局异常处理
 * 2全局数据绑定
 * 3全局数据预处理
 * @ExceptionHandler 注释的方法上，注释中参数 用于声明需要捕捉的异常，出现对应异常是通过该方法进行处理
 */
@RestControllerAdvice
public class GlobalExceptionResolver{
    ResponseView responseView = new ResponseView();
   //定义异常处理方法
    /* AuthenticationException 为认证异常（一下为认证异常的子异常）
            DisabledAccountException （禁用的帐号）
            LockedAccountException （锁定的帐号）
            UnknownAccountException（错误的帐号）
            ExcessiveAttemptsException（登录失败次数过多）
            IncorrectCredentialsException （错误的凭证）
            ExpiredCredentialsException （过期的凭证）
       AuthorizationException 为授权异常
            UnauthenticatedException (未认证异常)
            UnauthorizedException （角色或权限操作不匹配异常）
     */
    //捕捉shiro的异常
    /**
     * AuthorizationException 授权匹配异常
     * 异常说明： 权限不足，或者不属于某个角色之下
     * eq：该异常不在JWTFilter过滤链内，所以可以被捕捉并处理的异常
     * tip：目前测试环境该异常正常捕捉 22-1-21 10点02分
     * @return ResponseView
     */
    @ExceptionHandler(AuthorizationException.class)
    public ResponseView handle1022(AuthorizationException e){
        responseView.setRespOutMsgHeader(RespOutMsgHeader.error(false, ResultEnum.USER_AUTHORIZATION_ERROR.getMsg()+"具体原因：["+e.getMessage()+"]",ResultEnum.USER_AUTHORIZATION_ERROR.getCode()));
        return responseView;
    }

    /**
     *  UnauthorizedException 角色或权限操作不匹配异常
     * @param e
     * @return
     */
    @ExceptionHandler(UnauthorizedException.class)
    public ResponseView handle1023(UnauthorizedException e){
        responseView.setRespOutMsgHeader(RespOutMsgHeader.error(false, ResultEnum.USER_NOTMATCH_ROLE_OR_PEMISSION.getMsg()+"具体原因：["+e.getMessage()+"]",ResultEnum.USER_NOTMATCH_ROLE_OR_PEMISSION.getCode()));
        return responseView;
    }
    /*    *//**
     * 认证的用户被锁定的异常 LockedAccountException
     *//*
    @ExceptionHandler(LockedAccountException.class)
    public ResponseView handle1001(LockedAccountException e){
        responseView.setRespOutMsgHeader(RespOutMsgHeader.error(false, ResultEnum.USER_LOCKED.getMsg(),ResultEnum.USER_LOCKED.getCode()));
        return responseView;
    }

    /**
     * 未知账户，用户密码账户不正确 UnknownAccountException
     * @return
     */
//    @ExceptionHandler(UnknownAccountException.class)
//    public ResponseView handle1000(UnknownAccountException e){
//        responseView.setRespOutMsgHeader(RespOutMsgHeader.error(false, ResultEnum.USER_NULL_OR_USERACCOUNT_NOT_MACHE.getMsg(),ResultEnum.USER_NULL_OR_USERACCOUNT_NOT_MACHE.getCode()));
//        return responseView;
//    }

    /**
     * token过期 TokenExpiredException
     * @return
     *//*
    @ExceptionHandler(TokenExpiredException.class)
    public ResponseView handle602(TokenExpiredException e){
        responseView.setRespOutMsgHeader(RespOutMsgHeader.error(false, ResultEnum.TOKEN_OUT_OF_DATE.getMsg(),ResultEnum.TOKEN_OUT_OF_DATE.getCode()));
        return responseView;
    }



    *//**
     * token不匹配 IncorrectCredentialsException
     * @return
     *//*
    @ExceptionHandler(IncorrectCredentialsException.class)
    public ResponseView handle601(IncorrectCredentialsException e){
        responseView.setRespOutMsgHeader(RespOutMsgHeader.error(false, ResultEnum.TOKEN_NOT_MATCHE.getMsg(),ResultEnum.TOKEN_NOT_MATCHE.getCode()));
        return responseView;
    }*/
    /**
     * 捕捉系统其余异常并处理
     * @param e
     * @return
     */
//    @ExceptionHandler(Exception.class)
//    public ResponseView handle500(Exception e){
//        responseView.setRespOutMsgHeader(RespOutMsgHeader.error(false, ResultEnum.SYSTEM_ERROR.getMsg()+"/"+"["+e+"]",ResultEnum.SYSTEM_ERROR.getCode()));
//        return responseView;
//    }
}
